package com.googlecode.maven.plugin.appassembler.launcher.jsw;

import com.googlecode.maven.plugin.appassembler.App;
import com.googlecode.maven.plugin.appassembler.ResourceUtils;
import com.googlecode.maven.plugin.appassembler.Utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.plugin.MojoFailureException;
import org.springframework.core.io.Resource;

/**
 * Generates files for the JSW launcher.
 */
public final class JswLauncher
    {
    /**
     * Resource prefix of template files.
     */
    private static final String RESOURCE_PREFIX = "classpath:/com/googlecode/maven/plugin/appassembler/launcher/jsw/";

    /**
     * Constructs a new JswLauncher object.
     */
    private JswLauncher()
        {
        super();
        }

    /**
     * Generate files for the JSW launcher.
     *
     * @param configuration JSW launcher configuration.
     * @param app Application.
     * @param targetDirectory Target directory.
     * @throws MojoFailureException If this operation failed.
     */
    public static void apply(JswLauncherConfiguration configuration, App app,
            File targetDirectory)
            throws MojoFailureException
        {
        if ((app.getJavaParameters() != null) && !app.getJavaParameters().
                isEmpty())
            {
            if (configuration.getJavaParameters() == null)
                {
                configuration.setJavaParameters(new ArrayList<String>());
                }
            configuration.getJavaParameters().addAll(app.getJavaParameters());
            }

        Map<String, Object> vars = new HashMap<String, Object>();
        vars.put("app", app);
        vars.put("configuration", configuration);

        Properties platformProperties = new Properties();
        InputStream istrm = null;
        try
            {
            Resource resource = ResourceUtils.getResource(
                    RESOURCE_PREFIX + "platform.properties");
            istrm = resource.getInputStream();
            platformProperties.load(istrm);
            }
        catch (IOException e)
            {
            throw new MojoFailureException(
                    "Error reading JSW platform properties file", e);
            }
        finally
            {
            IOUtils.closeQuietly(istrm);
            }
        for (Map.Entry entry : platformProperties.entrySet())
            {
            String platformName = (String) entry.getKey();
            String[] platformFilenames = StringUtils.split((String) entry.
                    getValue(), ",");
            for (String platformFilename : platformFilenames)
                {
                platformFilename = StringUtils.trimToNull(platformFilename);
                Resource resource = ResourceUtils.
                        getResource(RESOURCE_PREFIX + platformFilename);
                File targetFile = new File(targetDirectory, platformFilename);
                ResourceUtils.copyResource(resource, targetFile);
                if (platformFilename.startsWith("bin/") || (platformFilename.
                        startsWith("lib/") && (platformFilename.endsWith(".a") || platformFilename.
                        endsWith(".so") || platformFilename.endsWith(".jnilib") || platformFilename.
                        endsWith(".sl"))))
                    {
                    Utils.addExecutableFile(app, platformFilename,
                            targetDirectory);
                    }
                }
            }

        String path = String.format("bin/%s", app.getAppName());
        File targetFile = new File(targetDirectory, path);
        ResourceUtils.copyTemplateResource(
                RESOURCE_PREFIX + "bin/AppCommand.ftl", targetFile, vars);
        Utils.addExecutableFile(app, path, targetDirectory);

        path = String.format("bin/%s.bat", app.getAppName());
        targetFile = new File(targetDirectory, path);
        ResourceUtils.copyTemplateResource(
                RESOURCE_PREFIX + "bin/AppCommand.bat.ftl", targetFile, vars);

        path = "conf/wrapper.conf";
        targetFile = new File(targetDirectory, path);
        ResourceUtils.copyTemplateResource(
                RESOURCE_PREFIX + "conf/wrapper.conf.ftl", targetFile, vars);

        path = String.format("init.d/%s", app.getAppName());
        targetFile = new File(targetDirectory, path);
        ResourceUtils.copyTemplateResource(
                RESOURCE_PREFIX + "init.d/sysvinitscript.ftl", targetFile, vars);
        Utils.addExecutableFile(app, path, targetDirectory);
        }
    }
